/**
 * 
 * iVprog/Alice: http://www.matematica.br/ivprog - http://www.alice.org
 * 
 * @description Left panel with tab to manage: variables, methods and functions
 * @see edu.cmu.cs.stage3.alice.authoringtool.JAliceFrame that extends JFrame, will contain 'DragFromComponent'
 * 
 * @author Jason Pratt / LOB;RR
 */

package edu.cmu.cs.stage3.alice.authoringtool;

import edu.cmu.cs.stage3.resourceBundle.I18n;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.SystemColor;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.border.Border;

import edu.cmu.cs.stage3.alice.authoringtool.py.AliceStyle;
import edu.cmu.cs.stage3.alice.authoringtool.dialog.NewQuestionContentPane;
import edu.cmu.cs.stage3.alice.authoringtool.dialog.NewResponseContentPane;
import edu.cmu.cs.stage3.alice.authoringtool.editors.variablegroupeditor.VariableGroupEditor;
import edu.cmu.cs.stage3.alice.authoringtool.event.ElementSelectionListener;
import edu.cmu.cs.stage3.alice.authoringtool.viewcontroller.CallToUserDefinedResponsePrototypeDnDPanel;
import edu.cmu.cs.stage3.alice.authoringtool.viewcontroller.ObjectArrayPropertyPanel;
import edu.cmu.cs.stage3.swing.ContentPane;
import edu.cmu.cs.stage3.swing.DialogManager;
import edu.cmu.cs.stage3.util.StringObjectPair;

public class DragFromComponent extends javax.swing.JPanel implements ElementSelectionListener {

 // Color definition
 // To define working areas (main function and others functions) see: src/edu/cmu/cs/stage3/alice/authoringtool/py/AliceStyle.java
 private static final java.awt.Color
   bgColorButton = AliceStyle.bgColorButton, // buttons: "create new method","create new function","capture pose"
   bgPanel = AliceStyle.bgPanel,             // panel background ('main's details')
   bgScrollPanel = AliceStyle.bgScrollPanel; // color to the left panels "variable,methods,funcions" - java.awt.Color.white

 public final static int PROPERTIES_TAB = 0;
 public final static int ANIMATIONS_TAB = 1;
 public final static int QUESTIONS_TAB = 2;
 public final static int OTHER_TAB = 3;

 protected edu.cmu.cs.stage3.alice.core.Element element;
 protected VariableGroupEditor variableGroupEditor = new VariableGroupEditor();
 protected NewResponseContentPane newResponseContentPane;
 protected NewQuestionContentPane newQuestionContentPane;
 protected edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty vars;
 protected edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty responses;
 protected ResponsesListener responsesListener = new ResponsesListener();
 protected edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty questions;
 protected QuestionsListener questionsListener = new QuestionsListener();
 protected edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty poses;
 protected PosesListener posesListener = new PosesListener();
 protected java.awt.GridBagConstraints constraints = new java.awt.GridBagConstraints( 0, 0, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.HORIZONTAL, new java.awt.Insets( 0, 0, 0, 0 ), 0, 0 );
 protected java.awt.GridBagConstraints glueConstraints = new java.awt.GridBagConstraints( 0, 0, 1, 1, 1.0, 1.0, java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.BOTH, new java.awt.Insets( 0, 0, 0, 0 ), 0, 0 );
 protected javax.swing.border.Border spacingBorder = javax.swing.BorderFactory.createEmptyBorder( 4, 0, 8, 0 );

 protected edu.cmu.cs.stage3.alice.core.event.ChildrenListener parentListener = new edu.cmu.cs.stage3.alice.core.event.ChildrenListener () {
  private edu.cmu.cs.stage3.alice.core.Element parent;
  public void childrenChanging (edu.cmu.cs.stage3.alice.core.event.ChildrenEvent ev) {
   if ((ev.getChild() == DragFromComponent.this.element) && (ev.getChangeType() == edu.cmu.cs.stage3.alice.core.event.ChildrenEvent.CHILD_REMOVED)) {
    parent = DragFromComponent.this.element.getParent();
    }
   }
  public void childrenChanged (edu.cmu.cs.stage3.alice.core.event.ChildrenEvent ev) {
   if ((ev.getChild() == DragFromComponent.this.element) && (ev.getChangeType() == edu.cmu.cs.stage3.alice.core.event.ChildrenEvent.CHILD_REMOVED)) {
    DragFromComponent.this.setElement( null );
    parent.removeChildrenListener( this );
    }
   }
  };
 protected edu.cmu.cs.stage3.alice.core.event.PropertyListener nameListener = new edu.cmu.cs.stage3.alice.core.event.PropertyListener () {
  public void propertyChanging( edu.cmu.cs.stage3.alice.core.event.PropertyEvent ev) { }
  public void propertyChanged( edu.cmu.cs.stage3.alice.core.event.PropertyEvent ev) {
   DragFromComponent.this.ownerLabel.setText( I18n.getString("detailsOf") + ": "+ ev.getValue().toString()); // Details of
   }
  };
 protected javax.swing.JButton newAnimationButton = new javax.swing.JButton(I18n.getString("createMethod")); // create new method
 protected javax.swing.JButton newQuestionButton = new javax.swing.JButton(I18n.getString("createFunction")); // create new function
 protected javax.swing.JButton capturePoseButton = new javax.swing.JButton(I18n.getString("capturePose")); // capture pose
 protected edu.cmu.cs.stage3.alice.core.response.UserDefinedResponse newlyCreatedAnimation;
 protected edu.cmu.cs.stage3.alice.core.question.userdefined.UserDefinedQuestion newlyCreatedQuestion;
 protected AuthoringTool authoringTool;
 protected ObjectArrayPropertyPanel miscPanel;

 protected java.util.HashSet panelsToClean = new java.util.HashSet();

 public DragFromComponent (AuthoringTool authoringTool) {
  // System.out.println("DragFromComponent.java: ");
  this.authoringTool = authoringTool;
  variableGroupEditor.setAuthoringTool( authoringTool );
  newResponseContentPane = new NewResponseContentPane();
  newQuestionContentPane = new NewQuestionContentPane();
  miscPanel = new ObjectArrayPropertyPanel( "Misc", authoringTool );
  jbInit();
  guiInit();
  }

 private void guiInit () {
  newAnimationButton.setBackground( bgColorButton ); // create new method
  newAnimationButton.setMargin( new java.awt.Insets( 2, 4, 2, 4 ) );
  newAnimationButton.addActionListener(
    new java.awt.event.ActionListener() {
     public void actionPerformed( java.awt.event.ActionEvent ev) {
      if (responses != null) {
       newResponseContentPane.reset( responses.getOwner() );
       int result = DialogManager.showDialog(this, newResponseContentPane ); //L
       if (result == ContentPane.OK_OPTION) {
        authoringTool.getUndoRedoStack().startCompound();
        try {
         edu.cmu.cs.stage3.alice.core.response.UserDefinedResponse response = new edu.cmu.cs.stage3.alice.core.response.UserDefinedResponse();
         response.name.set( newResponseContentPane.getNameValue() );
         responses.getOwner().addChild( response );
         responses.add( response );
        } finally {
         authoringTool.getUndoRedoStack().stopCompound();
         }
        }
       }
      }
     }
   );
  newQuestionButton.setBackground(bgColorButton);
  newQuestionButton.setMargin( new java.awt.Insets( 2, 4, 2, 4 ) );
  newQuestionButton.addActionListener(
    new java.awt.event.ActionListener() {
     public void actionPerformed (java.awt.event.ActionEvent ev) {
      if (questions != null) {
       newQuestionContentPane.reset( questions.getOwner() );
       int result = DialogManager.showDialog(this, newQuestionContentPane ); //L
       if (result == ContentPane.OK_OPTION) {
        authoringTool.getUndoRedoStack().startCompound();
        try {
         edu.cmu.cs.stage3.alice.core.question.userdefined.UserDefinedQuestion question = new edu.cmu.cs.stage3.alice.core.question.userdefined.UserDefinedQuestion();
         question.name.set( newQuestionContentPane.getNameValue() );
         question.valueClass.set( newQuestionContentPane.getTypeValue() );
         questions.getOwner().addChild( question );
         questions.add( question );
        } finally {
         authoringTool.getUndoRedoStack().stopCompound();
         }
        }
       }
      }
     }
   );

  capturePoseButton.setBackground(bgColorButton); //
  capturePoseButton.setMargin( new java.awt.Insets( 2, 4, 2, 4 ) );
  capturePoseButton.addActionListener(
    new java.awt.event.ActionListener() {
     public void actionPerformed( java.awt.event.ActionEvent ev) {
      if (poses != null) {
       authoringTool.getUndoRedoStack().startCompound();
      }
     }
    }
  );

  tabbedPane.setUI( new edu.cmu.cs.stage3.alice.authoringtool.util.AliceTabbedPaneUI() );
  tabbedPane.setOpaque( false );
  tabbedPane.setSelectedIndex( ANIMATIONS_TAB );

  // to make tab color match with the whole panel: bgcolor of the selected tab
  propertiesScrollPane.setBackground(bgScrollPanel);
  animationsScrollPane.setBackground(bgScrollPanel);
  questionsScrollPane.setBackground(bgScrollPanel);
  otherScrollPane.setBackground(bgScrollPanel);

  miscPanel.setExpanded( false );

  // tooltips
  // String cappedQuestionString = AuthoringToolResources.QUESTION_STRING.substring(0,1).toUpperCase()+AuthoringToolResources.QUESTION_STRING.substring(1);
  // is very complicated way to write: Function
  comboPanel.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipDetails")+"</font></html>" ); // This area displays the details<p>of the Selected Object.
  tabbedPane.setToolTipTextAt( PROPERTIES_TAB, "<html><font face=arial size=-1>"+I18n.getString("tipPropTab")+"</font></html>" ); // Open the Properties Tab<p>of the Selected Object.<p><p>Use this tab to view and edit<p>the Properties of the Selected Object.
  tabbedPane.setToolTipTextAt( ANIMATIONS_TAB, "<html><font face=arial size=-1>"+I18n.getString("tipMethodsTab")+"</font></html>" ); // Open the Methods Tab<p>of the Selected Object.<p><p>Use this tab to view and edit<p>the Methods of the Selected Object.
  tabbedPane.setToolTipTextAt( QUESTIONS_TAB, "<html><font face=arial size=-1>"+I18n.getString("tipEditTab")+"</font></html>" ); // Open the "+cappedQuestionString+"s"+" Tab<p>of the Selected Object.<p><p>Use this tab to view and edit<p>the "+cappedQuestionString+"s"+" of the Selected Object.
  newAnimationButton.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipCreateMethod")+"</font></html>" ); // Create a New Blank Method<p>and Open it for Editing.
  newQuestionButton.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipCreateFunc")+"</font></html>" ); // Create a New Blank "+cappedQuestionString+"<p>and Open it for Editing.
  propertiesPanel.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipPropTab")+"</font></html>" ); // Properties Tab<p><p>This tab allows you to view and edit<p>the Properties of the Selected Object.
  animationsPanel.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipMethodTab")+"</font></html>" ); // Methods Tab<p><p>Methods are the actions that an object knows how to do.<p>Most objects come with default methods, and you can<p>create your own methods as well.
  questionsPanel.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipFuncTab")+"</font></html>" ); // "+cappedQuestionString+"s"+" Tab<p><p>"+cappedQuestionString+"s"+" are the things that an object can<p>answer about themselves or the world.
  }

 public void paintComponent (java.awt.Graphics g) {
  super.paintComponent( g );
  // System.out.println("DragFromComponent.java: paintComponent(...): ----------------------------------------");
  g.setColor( java.awt.Color.black );
  g.drawRect( 0, 0, getWidth() - 1, getHeight() - 1 );
  }

 // ElementSelectionListener interface
 public void elementSelected (edu.cmu.cs.stage3.alice.core.Element element) {
  setElement( element );
  authoringTool.hackStencilUpdate();
  }

 public edu.cmu.cs.stage3.alice.core.Element getElement () {
  return element;
  }

 synchronized public void setElement (edu.cmu.cs.stage3.alice.core.Element element) {
  vars = null;
  if (responses != null) {
   responses.removeObjectArrayPropertyListener( responsesListener );
   responses = null;
   }
  if (questions != null) {
   questions.removeObjectArrayPropertyListener( questionsListener );
   questions = null;
   }
  if (poses != null) {
   poses.removeObjectArrayPropertyListener( posesListener );
   poses = null;
   }
  if (this.element != null) {
   if (this.element.getParent() != null) {
    this.element.getParent().removeChildrenListener( parentListener );
    }
   this.element.name.removePropertyListener( nameListener );
   }

  this.element = element;

  if (element != null) {
   ownerLabel.setText(I18n.getString("detailsOf")+": "+AuthoringToolResources.getReprForValue( element ));
   if (element.getParent() != null) {
    element.getParent().addChildrenListener( parentListener );
    }
   element.name.addPropertyListener( nameListener );
   if (element.getSandbox() == element) { //HACK: only show user-defined stuff for sandboxes
    vars = (edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty)element.getPropertyNamed( "variables" );
    responses = (edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty)element.getPropertyNamed( "responses" );
    if (responses != null) {
     responses.addObjectArrayPropertyListener( responsesListener );
     }
    questions = (edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty)element.getPropertyNamed( "questions" );
    if (questions != null) {
     questions.addObjectArrayPropertyListener( questionsListener );
     }
    }
   if (element instanceof edu.cmu.cs.stage3.alice.core.Transformable) {
    if (poses != null) {
     poses.addObjectArrayPropertyListener( posesListener );
     }
    }
  } else {
   ownerLabel.setText( "" );
   }

  int selectedIndex = tabbedPane.getSelectedIndex();
  refreshGUI();
  tabbedPane.setSelectedIndex( selectedIndex );
  }

 public int getSelectedTab () {
  return tabbedPane.getSelectedIndex();
  }

 protected void cleanPanels () {
  for( java.util.Iterator iter = panelsToClean.iterator(); iter.hasNext();) {
   javax.swing.JPanel panel = (javax.swing.JPanel)iter.next();
   java.awt.Component[] children = panel.getComponents();
   //LOB for (Component element2 : children)
   int t_tam = children!=null ? children.length : 0;
   for (int i_i=0; i_i<t_tam; i_i++) {
    if (children[i_i] instanceof edu.cmu.cs.stage3.alice.authoringtool.util.Releasable) { //L element2 instanceof edu.cmu.cs.stage3.alice.authoringtool.util.Releasable
     ((edu.cmu.cs.stage3.alice.authoringtool.util.Releasable)children[i_i]).release(); //L (...)element2).release();
     }
    }
   panel.removeAll();
   }
  panelsToClean.clear();
  }

 synchronized public void refreshGUI () {
  cleanPanels();
  propertiesPanel.removeAll();
  animationsPanel.removeAll();
  questionsPanel.removeAll();
  // System.out.println("DragFromComponent.java: refreshGUI(): ----------------------------------------");
  if (element != null) {
   constraints.gridy = 0;
   // Variable panel
   if (vars != null) {
    variableGroupEditor.setVariableObjectArrayProperty( vars );
    variableGroupEditor.setBackground(bgScrollPanel); 
    propertiesPanel.add( variableGroupEditor, constraints );
    constraints.gridy++;
    }

   // poses
   if (poses != null) {
    javax.swing.JPanel subPanel = new javax.swing.JPanel();
    subPanel.setBackground(bgScrollPanel); //
    subPanel.setLayout( new java.awt.GridBagLayout() );
    subPanel.setBorder( spacingBorder );
    panelsToClean.add( subPanel );

    int count = 0;
    java.awt.GridBagConstraints c = new java.awt.GridBagConstraints( 0, count, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 4, 2, 2, 2 ), 0, 0 );
    subPanel.add( capturePoseButton, c );

    propertiesPanel.add( subPanel, constraints );
    constraints.gridy++;
    }

   if (element instanceof edu.cmu.cs.stage3.alice.core.Sandbox) {
    constraints.gridy++;
    propertiesPanel.add( javax.swing.Box.createVerticalStrut( 8 ), constraints );
    constraints.gridy++;
    }
   if (element.data.get( "modeled by" ) != null) {
    propertiesPanel.add( new javax.swing.JLabel( "modeled by: " + element.data.get( "modeled by" ) ), constraints );
    constraints.gridy++;
    }
   if (element.data.get( "painted by" ) != null) {
    propertiesPanel.add( new javax.swing.JLabel( "painted by: " + element.data.get( "painted by" ) ), constraints );
    constraints.gridy++;
    }
   if (element.data.get( "programmed by" ) != null) {
    propertiesPanel.add( new javax.swing.JLabel( "programmed by: " + element.data.get( "programmed by" ) ), constraints );
    constraints.gridy++;
    }

   glueConstraints.gridy = constraints.gridy;
   propertiesPanel.add( javax.swing.Box.createGlue(), glueConstraints );

   constraints.gridy = 0;

   // user-defined responses
   if (responses != null) {
    javax.swing.JPanel subPanel = new javax.swing.JPanel();
    subPanel.setBackground(bgScrollPanel); // the top portion of the "method" panel (containing buttons "play,edit,create new method")
    subPanel.setLayout( new java.awt.GridBagLayout() );
    subPanel.setBorder( spacingBorder );
    panelsToClean.add( subPanel );

    int count = 0;
    Object[] responseArray = responses.getArrayValue();
    //LOB for (Object element2 : responseArray)
    int t_tam = responseArray!=null ? responseArray.length : 0;
    for (int i_i=0; i_i<t_tam; i_i++) {
     edu.cmu.cs.stage3.alice.core.Response response = (edu.cmu.cs.stage3.alice.core.Response)responseArray[i_i]; //L (...)element2;

     if (response instanceof edu.cmu.cs.stage3.alice.core.response.UserDefinedResponse) {
      edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedResponsePrototype callToUserDefinedResponsePrototype = new edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedResponsePrototype( (edu.cmu.cs.stage3.alice.core.response.UserDefinedResponse)response );
      javax.swing.JComponent gui = edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.getGUI( callToUserDefinedResponsePrototype );
      if (gui != null) {
       edu.cmu.cs.stage3.alice.authoringtool.util.EditObjectButton editButton = edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.getEditObjectButton( response, gui );
       editButton.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipOpenMethod")+"</font></html>" ); // Open this method for editing.
       javax.swing.JPanel guiPanel = new javax.swing.JPanel();
       panelsToClean.add( guiPanel );
       guiPanel.setBackground(bgScrollPanel); // the border of button ("edit")
       guiPanel.setLayout( new java.awt.GridBagLayout() );
       guiPanel.add( gui, new java.awt.GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, java.awt.GridBagConstraints.SOUTHWEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 0, 0, 0, 0 ), 0, 0 ) );
       guiPanel.add( editButton, new java.awt.GridBagConstraints( 1, 0, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.SOUTHWEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 0, 4, 0, 0 ), 0, 0 ) );
       java.awt.GridBagConstraints constraints = new java.awt.GridBagConstraints( 0, count, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 2, 2, 2, 2 ), 0, 0 );
       subPanel.add( guiPanel, constraints );
       count++;
       if ((newlyCreatedAnimation == response) && (gui instanceof CallToUserDefinedResponsePrototypeDnDPanel)) {
        //        ((CallToUserDefinedResponsePrototypeDnDPanel)gui).editName();
        authoringTool.editObject( newlyCreatedAnimation );
        newlyCreatedAnimation = null;
        }
      } else {
       AuthoringTool.getInstance().showErrorDialog( "Unable to create gui for callToUserDefinedResponsePrototype: " + callToUserDefinedResponsePrototype, null );
       }
     } else {
      AuthoringTool.getInstance().showErrorDialog( "Response is not a userDefinedResponse: " + response, null );
      }
     }

    java.awt.GridBagConstraints c = new java.awt.GridBagConstraints( 0, count, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 4, 2, 2, 2 ), 0, 0 );
    subPanel.add( newAnimationButton, c );

    animationsPanel.add( subPanel, constraints );
    constraints.gridy++;
    } // if (responses != null)

   glueConstraints.gridy = constraints.gridy;
   animationsPanel.add( javax.swing.Box.createGlue(), glueConstraints );

   // user-defined questions
   constraints.gridy = 0;
   if (questions != null) {
    javax.swing.JPanel subPanel = new javax.swing.JPanel();
    subPanel.setBackground(bgScrollPanel); // the top portion of the panel "function"
    subPanel.setLayout( new java.awt.GridBagLayout() );
    subPanel.setBorder( spacingBorder );
    panelsToClean.add( subPanel );

    int count = 0;
    Object[] questionsArray = questions.getArrayValue();
    //LOB for (Object element2 : questionsArray)
    int t_tam = questionsArray!=null ? questionsArray.length : 0;
    for (int i_i=0; i_i<t_tam; i_i++) {
     edu.cmu.cs.stage3.alice.core.Question question = (edu.cmu.cs.stage3.alice.core.Question)questionsArray[i_i]; //L (...)element2;

     if (question instanceof edu.cmu.cs.stage3.alice.core.question.userdefined.UserDefinedQuestion) {
      edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedQuestionPrototype callToUserDefinedQuestionPrototype = new edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedQuestionPrototype( (edu.cmu.cs.stage3.alice.core.question.userdefined.UserDefinedQuestion)question );
      javax.swing.JComponent gui = edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.getGUI( callToUserDefinedQuestionPrototype );
      if (gui != null) {
       edu.cmu.cs.stage3.alice.authoringtool.util.EditObjectButton editButton = edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.getEditObjectButton( question, gui );
       editButton.setToolTipText( "<html><font face=arial size=-1>"+I18n.getString("tipOpenQuestion")+"</font></html>" ); // Open this question for editing.
       javax.swing.JPanel guiPanel = new javax.swing.JPanel();
       panelsToClean.add( guiPanel );
       guiPanel.setBackground(bgScrollPanel); // the
       guiPanel.setLayout( new java.awt.GridBagLayout() );
       guiPanel.add( gui, new java.awt.GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, java.awt.GridBagConstraints.SOUTHWEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 0, 0, 0, 0 ), 0, 0 ) );
       guiPanel.add( editButton, new java.awt.GridBagConstraints( 1, 0, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.SOUTHWEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 0, 4, 0, 0 ), 0, 0 ) );
       java.awt.GridBagConstraints constraints = new java.awt.GridBagConstraints( 0, count, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 2, 2, 2, 2 ), 0, 0 );
       subPanel.add( guiPanel, constraints );
       count++;
       if (newlyCreatedQuestion == question) {
        authoringTool.editObject( newlyCreatedQuestion );
        newlyCreatedQuestion = null;
        }
      } else {
       AuthoringTool.getInstance().showErrorDialog( "Unable to create gui for callToUserDefinedQuestionPrototype: " + callToUserDefinedQuestionPrototype, null );
       }
     } else {
      throw new RuntimeException( "ERROR: question is not a userDefinedQuestion" );
      }
     }

    java.awt.GridBagConstraints c = new java.awt.GridBagConstraints( 0, count, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 4, 2, 2, 2 ), 0, 0 );
    subPanel.add( newQuestionButton, c );

    questionsPanel.add( subPanel, constraints );
    constraints.gridy++;
    }

   // question panels
   java.util.Vector questionStructure = AuthoringToolResources.getQuestionStructure( element.getClass() );
   if (questionStructure != null) {
    for( java.util.Iterator iter = questionStructure.iterator(); iter.hasNext();) {
     StringObjectPair sop = (StringObjectPair)iter.next();
     String groupName = sop.getString();
     java.util.Vector questionNames = (java.util.Vector)sop.getObject();

     javax.swing.JPanel subPanel = new javax.swing.JPanel();
     subPanel.setBackground(bgScrollPanel); 
     subPanel.setLayout( new java.awt.GridBagLayout() );
     panelsToClean.add( subPanel );

     edu.cmu.cs.stage3.alice.authoringtool.util.ExpandablePanel expandPanel = new edu.cmu.cs.stage3.alice.authoringtool.util.ExpandablePanel();
     expandPanel.setTitle( groupName );
     expandPanel.setContent( subPanel );

     if (questionNames != null) {
      int i = 0;
      for( java.util.Iterator jter = questionNames.iterator(); jter.hasNext();) {
       String className = (String)jter.next();
       try {
        Class questionClass = Class.forName( className );
        java.util.LinkedList known = new java.util.LinkedList();
        String format = AuthoringToolResources.getFormat( questionClass );
        edu.cmu.cs.stage3.alice.authoringtool.util.FormatTokenizer tokenizer = new edu.cmu.cs.stage3.alice.authoringtool.util.FormatTokenizer( format );
        while (tokenizer.hasMoreTokens()) {
         String token = tokenizer.nextToken();
         if (token.startsWith( "<<<" ) && token.endsWith( ">>>" )) {
          String propertyName = token.substring( token.lastIndexOf( "<" ) + 1, token.indexOf( ">" ) );
          known.add( new StringObjectPair( propertyName, element ) );
          }
         }
        if (edu.cmu.cs.stage3.alice.core.question.PartKeyed.class.isAssignableFrom( questionClass )) { // special case hack
         known.add( new StringObjectPair( "key", "" ) );
         }
        StringObjectPair[] knownPropertyValues = (StringObjectPair[])known.toArray( new StringObjectPair[0] );

        String[] desiredProperties = AuthoringToolResources.getDesiredProperties( questionClass );
        if (edu.cmu.cs.stage3.alice.core.question.PartKeyed.class.isAssignableFrom( questionClass )) { // special case hack
         desiredProperties = new String[0];
         }
        edu.cmu.cs.stage3.alice.authoringtool.util.ElementPrototype elementPrototype = new edu.cmu.cs.stage3.alice.authoringtool.util.ElementPrototype( questionClass, knownPropertyValues, desiredProperties );
        javax.swing.JComponent gui = edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.getGUI( elementPrototype );
        if (gui != null) {
         java.awt.GridBagConstraints constraints = new java.awt.GridBagConstraints( 0, i, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 2, 2, 2, 2 ), 0, 0 );
         subPanel.add( gui, constraints );
         i++;
        } else {
         AuthoringTool.getInstance().showErrorDialog( "Unable to create gui for elementPrototype: " + elementPrototype, null );
         }
       } catch( ClassNotFoundException e) {
        AuthoringTool.getInstance().showErrorDialog( "Unable to create gui for class: " + className, e );
        }
       }
      }

     questionsPanel.add( expandPanel, constraints );
     constraints.gridy++;
     }
    }
   glueConstraints.gridy = constraints.gridy;
   questionsPanel.add( javax.swing.Box.createGlue(), glueConstraints );
   }
  revalidate();
  repaint();
  }

 public class ResponsesListener implements edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyListener {
  public void objectArrayPropertyChanging (edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent ev) { }
  public void objectArrayPropertyChanged (edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent ev) {
   if (ev.getChangeType() == edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent.ITEM_INSERTED) {
    newlyCreatedAnimation = (edu.cmu.cs.stage3.alice.core.response.UserDefinedResponse)ev.getItem();
    }
   int selectedIndex = tabbedPane.getSelectedIndex();
   refreshGUI();
   tabbedPane.setSelectedIndex( selectedIndex );
   }
  }

 public class QuestionsListener implements edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyListener {
  public void objectArrayPropertyChanging (edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent ev) { }
  public void objectArrayPropertyChanged (edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent ev) {
   if (ev.getChangeType() == edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent.ITEM_INSERTED) {
    newlyCreatedQuestion = (edu.cmu.cs.stage3.alice.core.question.userdefined.UserDefinedQuestion)ev.getItem();
    }
   int selectedIndex = tabbedPane.getSelectedIndex();
   refreshGUI();
   tabbedPane.setSelectedIndex( selectedIndex );
   }
  }

 public class PosesListener implements edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyListener {
  public void objectArrayPropertyChanging (edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent ev) { }
  public void objectArrayPropertyChanged (edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent ev) {
   int selectedIndex = tabbedPane.getSelectedIndex();
   refreshGUI();
   tabbedPane.setSelectedIndex( selectedIndex );
   }
  }

 ////////////////////
 // Autogenerated
 ////////////////////

 BorderLayout borderLayout1 = new BorderLayout();
 JPanel propertySubPanel = new JPanel();
 BorderLayout borderLayout2 = new BorderLayout();
 Border border1;
 //JScrollPane propertyScrollPane = new JScrollPane();
 Border border2;
 Border border3;
 Border border4;
 Border border5;
 Border border6;
 Border border7;
 JPanel comboPanel = new JPanel();
 JLabel ownerLabel = new JLabel();
 GridBagLayout gridBagLayout1 = new GridBagLayout();
 JTabbedPane tabbedPane = new JTabbedPane();
 JScrollPane propertiesScrollPane = new JScrollPane();
 JScrollPane animationsScrollPane = new JScrollPane();
 GridBagLayout gridBagLayout2 = new GridBagLayout();
 JPanel propertiesPanel = new JPanel();
 GridBagLayout gridBagLayout3 = new GridBagLayout();
 JPanel animationsPanel = new JPanel();
 JScrollPane questionsScrollPane = new JScrollPane();
 JPanel questionsPanel = new JPanel();
 GridBagLayout gridBagLayout4 = new GridBagLayout();
 JScrollPane otherScrollPane = new JScrollPane();
 JPanel otherPanel = new JPanel();
 GridBagLayout gridBagLayout5 = new GridBagLayout();
 Border border8;
 Border border9;

 private void jbInit () {
  border1 = BorderFactory.createEmptyBorder(2,0,0,0);
  border2 = BorderFactory.createLineBorder(SystemColor.controlText,1);
  border3 = BorderFactory.createCompoundBorder(border2,border1);
  border4 = BorderFactory.createEmptyBorder(8,8,8,8);
  border5 = BorderFactory.createEmptyBorder(2,2,2,2);
  border6 = BorderFactory.createLineBorder(SystemColor.controlText,1);
  border7 = BorderFactory.createCompoundBorder(border6,border5);
  border8 = BorderFactory.createEmptyBorder();
  border9 = BorderFactory.createLineBorder(Color.black,1);
  this.setLayout(borderLayout1);
  propertySubPanel.setLayout(borderLayout2);
  propertySubPanel.setBorder(border1);
  propertySubPanel.setMinimumSize(new Dimension(0, 0));
  propertySubPanel.setOpaque(false);

  this.setBackground(bgPanel);

  this.setMinimumSize(new Dimension(0, 0));
  borderLayout2.setHgap(8);
  borderLayout2.setVgap(6);
  comboPanel.setLayout(gridBagLayout1);
  ownerLabel.setForeground(Color.black);
  ownerLabel.setText(I18n.getString("ownerDetails")); // owner\'s details
  propertiesPanel.setBackground(bgScrollPanel); // the body of the variable panel 
  propertiesPanel.setLayout(gridBagLayout2);
  animationsPanel.setBackground(bgScrollPanel); // the body of the methods panel (above the "create new method" button)
  animationsPanel.setLayout(gridBagLayout3);
  questionsPanel.setBackground(bgScrollPanel); // the body of the function panel (above the "create new function" button, bellow expressions...)
  questionsPanel.setLayout(gridBagLayout4);
  otherPanel.setBackground(bgScrollPanel); // the body of the panel (above the "" button)
  otherPanel.setLayout(gridBagLayout5);
  propertiesScrollPane.getViewport().setBackground(Color.white);
  propertiesScrollPane.setBorder(null);
  animationsScrollPane.getViewport().setBackground(Color.white);
  animationsScrollPane.setBorder(null);
  questionsScrollPane.getViewport().setBackground(Color.white);
  questionsScrollPane.setBorder(null);
  otherScrollPane.getViewport().setBackground(Color.white);
  otherScrollPane.setBorder(null);
  comboPanel.setOpaque(false);
  this.add(propertySubPanel, BorderLayout.CENTER);
  propertySubPanel.add(comboPanel, BorderLayout.NORTH);
  comboPanel.add(ownerLabel,  new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0
    ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 8, 0, 0), 0, 0));
  propertySubPanel.add(tabbedPane, BorderLayout.CENTER);
  tabbedPane.add(propertiesScrollPane, I18n.getString("variables"));
  propertiesScrollPane.getViewport().add(propertiesPanel, null);
  tabbedPane.add(animationsScrollPane, I18n.getString("methods"));
  tabbedPane.add(questionsScrollPane, I18n.getString("functions"));
  otherScrollPane.getViewport().add(otherPanel, null);
  questionsScrollPane.getViewport().add(questionsPanel, null);
  animationsScrollPane.getViewport().add(animationsPanel, null);
  }

 }
